<template>
	<div class="cl-wang-editor">
		<div class="cl-wang-editor__content" ref="wangeditor"></div>
		<input type="hidden" :value="content" />
	</div>
</template>
<script>
import E from "wangeditor";
import hljs from "highlight.js";
import "highlight.js/styles/vs.css";
import dayjs from "dayjs";
import { mapGetters } from "vuex";
import emitter from "element-ui/src/mixins/emitter";
import { baseUrl } from "@/config/env";
export { E };
export default {
	name: "cl-wang-editor",
	mixins: [emitter],
	props: {
		value: {
			type: String,
			default: ""
		},
		height: {
			type: Number,
			default: 300
		},
		validateEvent: {
			type: Boolean,
			default: true
		},
		placeholder: {
			type: String,
			default: "请输入正文"
		},
		autofocus: {
			type: Boolean,
			default: false
		},
		// 菜单
		menus: {
			type: Array,
			default: () => [
				"head",
				"bold",
				"fontSize",
				"fontName",
				"italic",
				"underline",
				"strikeThrough",
				"indent",
				"lineHeight",
				"foreColor",
				"backColor",
				"link",
				"list",
				"todo",
				"justify",
				"quote",
				"emoticon",
				"image",
				"video",
				"table",
				"code",
				"splitLine",
				"undo",
				"redo"
			]
		},
		// 自定义扩展时使用
		extend: Function,
		disabled: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			editor: null,
			content: this.value
		};
	},
	computed: {
		...mapGetters(["token", "modules"])
	},
	watch: {
		value: {
			immediate: true,
			handler(v) {
				this.content = v;
			}
		},
		content(v) {
			this.$emit("input", v);
			if (this.validateEvent) {
				this.dispatch("ElFormItem", "el.form.change", [v]);
			}
		},
		disabled(v) {
			if (v) {
				this.disable();
				return;
			}
			this.enable();
		}
	},
	mounted() {
		this.init();
	},
	beforeDestroy() {
		this.dispose();
	},
	methods: {
		init() {
			// console.log("init wangeditor");
			this.$nextTick(() => {
				if (this.editor) {
					this.setHtml(this.value);
					return;
				}
				const editor = new E(this.$refs.wangeditor);
				// 配置 onchange 回调函数
				editor.config.onchange = html => this.onChange(html);
				// 编辑区域失焦
				editor.config.onblur = html => this.onBlur(html);
				// 编辑区域聚焦
				editor.config.onfocus = html => this.onFocus(html);

				// 隐藏菜单栏提示
				editor.config.showMenuTooltips = true;
				//  placeholder 的提示文字
				editor.config.placeholder = this.placeholder;
				// 自动 focus
				editor.config.focus = this.autofocus;
				editor.config.height = this.height;
				// 挂载highlight插件
				editor.highlight = hljs;
				// imeout 即上传接口等待的最大时间
				editor.config.uploadImgTimeout = 60 * 1000;
				// 请求api地址
				editor.config.uploadImgServer = `${baseUrl}/index/uposs`;
				// 上传头
				editor.config.uploadImgHeaders = {
					token: this.token
				};
				// 文件名
				editor.config.uploadFileName = "file";
				// 参数
				editor.config.uploadImgParams = {
					file: "file/" + dayjs().format("YYYY-MM-DD"),
					dirname: "upload/" + dayjs().format("YYYY-MM-DD")
				};
				// 一次传一张
				editor.config.uploadImgMaxLength = 1;
				// 钩子
				editor.config.uploadImgHooks = {
					// 	before: xhr => {
					// 		console.log(xhr);
					// 		// 可阻止图片上传
					// 		// return {
					// 		// 	prevent: true,
					// 		// 	msg: "需要提示给用户的错误信息"
					// 		// };
					// 	},
					// 	// 图片上传并返回了结果，图片插入已成功
					// 	success: xhr => {
					// 		console.log("success", xhr);
					// 		this.$message.success("上传成功");
					// 	},
					// 	// 图片上传并返回了结果，但图片插入时出错了
					// 	fail: (xhr, editor, resData) => {
					// 		console.log("fail", resData);
					// 		this.$message.error("插入失败");
					// 	},
					// 	// 上传图片出错，一般为 http 请求的错误
					// 	error: (xhr, editor, resData) => {
					// 		console.log("error", xhr, resData);
					// 		this.$message.error("上传出错");
					// 	},
					// 	// 上传图片超时
					// 	timeout: xhr => {
					// 		console.log("timeout");
					// 		this.$message.error("上传超时");
					// 	}
					customInsert: (insertImgFn, result) => {
						// insertImgFn 可把图片插入到编辑器，传入图片 src ，执行函数即可
						insertImgFn(result.data);
					}
				};
				editor.config.customAlert = (s, t) => {
					switch (t) {
						case "success":
							this.$message.success(s || "上传成功");
							break;
						case "info":
							this.$message.info(s);
							break;
						case "warning":
							this.$message.warning(s);
							break;
						case "error":
							this.$message.error(s);
							break;
						default:
							this.$message.info(s);
							break;
					}
				};
				// 默认情况下，显示所有菜单
				editor.config.menus = this.menus;
				this.extend && this.extend(editor, E);
				editor.create(); // 创建富文本实例
				this.editor = editor;
				this.setHtml(this.value);
				this.$emit("init", this.editor);
			});
		},
		dispose() {
			// 调用销毁 API 对当前编辑器实例进行销毁
			if (this.editor) {
				this.editor.destroy();
				this.editor = null;
				this.content = "";
			}
		},
		enable() {
			this.editor && this.editor.enable();
		},
		disable() {
			this.editor && this.editor.disable();
		},
		// 配置 onchange 回调函数
		onChange(html) {
			let content = html;
			if (html === "<p><br/></p>") {
				content = "";
			}
			this.$emit("change", content);
			this.content = content;
		},
		// 编辑区域失焦
		onBlur(html) {
			this.content = html;
			this.$emit("blur", html);
			this.$emit("input", html);
			this.$nextTick(() => {
				if (this.validateEvent) {
					this.dispatch("ElFormItem", "el.form.blur", [html]);
				}
			});
		},
		// 编辑区域聚焦
		onFocus(html) {
			this.$emit("focus", html);
		},
		setFocus() {
			this.editor && this.editor.config;
		},
		// 追加新内容
		append(html) {
			this.editor && this.editor.txt.append(html);
		},
		//  重新设置编辑器内容
		setHtml(html) {
			this.editor && this.editor.txt.html(html ?? "");
		},
		// 获取 html
		getHtml() {
			this.editor && this.editor.txt.html();
		},
		// 获取 text
		getText() {
			this.editor && this.editor.txt.text();
		},
		// 清空内容
		clear() {
			this.editor && this.editor.txt.clear();
		},
		// 获取 JSON
		getJSON() {
			this.editor && this.editor.txt.getJSON();
		},
		// 设置 JSON
		setJSON() {
			this.editor && this.editor.txt.setJSON();
		}
	}
};
</script>
<style lang="scss">
.cl-wang-editor {
	.w-e-toolbar,
	.w-e-text-container {
		transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
	}
	.w-e-toolbar {
		border-radius: 4px 4px 0 0;
		z-index: 1001 !important;
	}
	.w-e-text-container {
		border-radius: 0 0 4px 4px;
		z-index: 1000 !important;
		.w-e-todo {
			margin-left: 10px;
			li {
				padding-left: 10px;
			}
		}
	}
}
.el-form-item.is-error .cl-wang-editor {
	.w-e-toolbar {
		border: 1px solid #f56c6c !important;
		border-bottom: 1px solid #eee !important;
	}
	.w-e-text-container {
		border: 1px solid #f56c6c !important;
		border-top: none !important;
		transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
	}
}
</style>
